package com.bill99.testmp.testmanage.domain.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import com.bill99.riaframework.common.helper.Bill99Logger;
import com.bill99.riaframework.common.utils.DateUtil;
import com.bill99.testmp.framework.helper.HttpFixtureHelper;
import com.bill99.testmp.framework.helper.JenkinsSvnJobHelper;
import com.bill99.testmp.ta.mdp.api.common.TaJobUtil;
import com.bill99.testmp.ta.mdp.api.common.TaTaskRequestBo;
import com.bill99.testmp.ta.mdp.api.common.TaTaskResponesBo;
import com.bill99.testmp.ta.mdp.api.common.UnitUtil;
import com.bill99.testmp.testmanage.domain.TaTaskTiggerService;
import com.bill99.testmp.testmanage.orm.entity.TaProject;
import com.bill99.testmp.testmanage.orm.entity.TaTask;
import com.bill99.testmp.testmanage.orm.ibatis.dto.AutoTiggerTaskDto;
import com.bill99.testmp.testmanage.orm.ibatis.dto.JinkensJobMethodDto;
import com.bill99.testmp.testmanage.orm.ibatis.dto.TestProjectDto;
import com.bill99.testmp.testmanage.orm.ibatis.dto.TestTaTaskLogDto;
import com.bill99.testmp.testmanage.orm.manager.AssoTaTaskTestCaseMng;
import com.bill99.testmp.testmanage.orm.manager.TaMng;
import com.bill99.testmp.testmanage.orm.manager.TaProjectMng;
import com.bill99.testmp.testmanage.orm.manager.TaTaskMng;

public class TaTaskTiggerServiceImpl implements TaTaskTiggerService {
	private Bill99Logger logger = Bill99Logger.getLogger(this.getClass());

	private TaTaskMng taTaskMng;
	private TaMng taMng;
	private TaProjectMng taProjectMng;

	private String jenKinsUrl;
	private String svnUserName;
	private String svnPassword;
	private String jenKinsJobDelaySec;

	private AssoTaTaskTestCaseMng assoTaTaskTestCaseMng;

	public void checkTaskTigger() {
		TaTaskRequestBo taTaskRequestBo = null;
		List<TaTask> taTasks = taTaskMng.getOnTimeTask();
		if (taTasks != null) {
			for (TaTask taTask : taTasks) {
				taTaskRequestBo = new TaTaskRequestBo();
				taTaskRequestBo.setStageId(UnitUtil.STAGEID_STAGE2);
				taTaskRequestBo.setGroupId(UnitUtil.GROUPID_T);

				tiggerTask(taTask.getIdTaTask(), taTaskRequestBo);
				taTask.setState(Boolean.FALSE);//finish
				taTask.setUpdateDate(new Date());
				taTaskMng.update(taTask);
			}
		}
	}

	public void tiggerTask(Long idTaTask, TaTaskRequestBo taTaskRequestBo) {
		List<JinkensJobMethodDto> jinkensJobMethodDtos = taMng.getJinkensJobMethodsByTask(idTaTask);

		if (jinkensJobMethodDtos == null || jinkensJobMethodDtos.size() < 1) {
			logger.info("IDTATASK:" + idTaTask + " js not asso");//脚本无关联
			return;
		}
		Map<String, List<JinkensJobMethodDto>> jobMap = new HashMap<String, List<JinkensJobMethodDto>>();

		List<JinkensJobMethodDto> jinkensJobMethodDtoTmps = null;
		for (JinkensJobMethodDto jinkensJobMethodDto : jinkensJobMethodDtos) {
			if (jobMap.get(jinkensJobMethodDto.getJobName()) != null) {
				jinkensJobMethodDtoTmps = jobMap.get(jinkensJobMethodDto.getJobName());
			} else {
				jinkensJobMethodDtoTmps = new ArrayList<JinkensJobMethodDto>();
			}
			jinkensJobMethodDtoTmps.add(jinkensJobMethodDto);
			jobMap.put(jinkensJobMethodDto.getJobName(), jinkensJobMethodDtoTmps);
		}
		if (jobMap.size() > 0) {//对用多个任务
			for (Entry<String, List<JinkensJobMethodDto>> entry : jobMap.entrySet()) {
				String jobName = entry.getKey();
				TaProject taProject = taProjectMng.getTaProject(jobName);

				try {
					JenkinsSvnJobHelper.init(taProject.getTaSvnUrl(), svnUserName, svnPassword);

					String filePath = "/xmlfileset/" + jobName;
					String xmlPath = filePath + "/jenkins_job.xml";
					JenkinsSvnJobHelper.parseJenkinsJobXml(filePath, xmlPath, jobName, entry.getValue(), taMng);

				} catch (Exception e) {
					e.printStackTrace();
				}
				requestJob(jobName, idTaTask, taTaskRequestBo);// jinkens
			}
		}
	}

	public TaTaskResponesBo triggerTaTask(TaTaskRequestBo taTaskRequestBo) {

		if (!StringUtils.hasLength(taTaskRequestBo.getTaTaskId()) || taTaskRequestBo.getTestProjectId() == null || taTaskRequestBo.getTestPlanId() == null
				|| taTaskRequestBo.getIdTestTaTask() == null) {
			logger.info(Boolean.FALSE + " invalid task");
			return new TaTaskResponesBo(Boolean.FALSE, "测试任务不合法");
		}

		if (taTaskRequestBo.getIsActual() == null || taTaskRequestBo.getTriggerTime() == null) {
			taTaskRequestBo.setIsActual(Boolean.TRUE);
		}

		List<Long> idTestTaTaskProjects = assoTaTaskTestCaseMng.findTestTaTaskProjects(taTaskRequestBo.getIdTestTaTask());

		if (idTestTaTaskProjects == null || idTestTaTaskProjects.size() == 0) {
			return new TaTaskResponesBo(Boolean.FALSE, "没有可执行的用例");
		}

		for (Long idTestProject : idTestTaTaskProjects) {

			List<Long> tcIds = assoTaTaskTestCaseMng.findTestTaTaskTcs(taTaskRequestBo.getIdTestTaTask(), idTestProject);

			taTaskRequestBo.setTcIds(tcIds.toArray(new Long[tcIds.size()]));
			taTaskRequestBo.setTestProjectId(idTestProject);

			TaTask taTask = taTaskMng.getTaTask(taTaskRequestBo.getTaTaskId(), taTaskRequestBo.getTestPlanId(), idTestProject);
			if (taTask != null) {
				logger.info("TaTaskId:" + taTaskRequestBo.getTaTaskId() + "  &TestPlanId:" + taTaskRequestBo.getTestPlanId() + " redo task,not run!");
				//				return new TaTaskResponesBo(Boolean.FALSE, "任务重复,不执行");
			}
			taTask = new TaTask();
			BeanUtils.copyProperties(taTaskRequestBo, taTask);
			taTask.setState(Boolean.TRUE);
			taTask = taTaskMng.save(taTask);

			//批量插入中间表
			assoTaTaskTestCaseMng.insertTaTaskTcs4Batch(taTask.getIdTaTask(), taTaskRequestBo.getTcIds());

			if (taTask.getIsActual()) {
				this.tiggerTask(taTask.getIdTaTask(), taTaskRequestBo);
				taTask.setTriggerTime(null);
				taTask.setState(Boolean.FALSE);
				taTaskMng.update(taTask);
				logger.info("TaTaskId:" + taTaskRequestBo.getTaTaskId() + "  &TestPlanId:" + taTaskRequestBo.getTestPlanId() + " actual task,run now!");
				//				return new TaTaskResponesBo(Boolean.TRUE, "实时任务,立即执行");
			}
		}
		//		logger.info("TaTaskId:" + taTaskRequestBo.getTaTaskId() + "  &TestPlanId:" + taTaskRequestBo.getTestPlanId() + " not actual,schedule run!");
		//		return new TaTaskResponesBo(Boolean.TRUE, "非实时任务,由定时器执行");
		return new TaTaskResponesBo(Boolean.TRUE, "任务触发成功");

	}

	public void autoTiggerTask() {
		List<TestProjectDto> testProjectDtos = taMng.findTestProjects();//获取所有项目组
		//计算当前需要运行的cycleId
		String cycleId = getCycleId();
		for (TestProjectDto testProjectDto : testProjectDtos) {
			autoTiggerTaskProcess(testProjectDto, cycleId);
		}

	}

	private void autoTiggerTaskProcess(TestProjectDto testProjectDto, String cycleId) {
		List<AutoTiggerTaskDto> autoTiggerTasks = taMng.getTcIdsByCycleProject(testProjectDto.getTeemId(), cycleId);
		String key = null;
		List<Long> tcIds = null;
		Map<String, List<Long>> tmpMap = new HashMap<String, List<Long>>();
		for (AutoTiggerTaskDto autoTiggerTaskDto : autoTiggerTasks) {
			key = autoTiggerTaskDto.getTestPlanId() + "_" + autoTiggerTaskDto.getPlanStepId();
			if (tmpMap.get(key) != null) {
				tcIds = tmpMap.get(key);
			} else {
				tcIds = new ArrayList<Long>();
			}
			tcIds.add(autoTiggerTaskDto.getTcId());
			tmpMap.put(key, tcIds);
		}
		if (tmpMap.size() > 0) {
			for (Entry<String, List<Long>> tntry : tmpMap.entrySet()) {
				TaTaskRequestBo taTaskRequestBo = new TaTaskRequestBo();

				String[] ids = tntry.getKey().split("_");

				taTaskRequestBo.setIsActual(true);
				taTaskRequestBo.setTestPlanId(Long.valueOf(ids[0]));
				taTaskRequestBo.setPlanStepId(Long.valueOf(ids[1]));
				taTaskRequestBo.setTestProjectId(testProjectDto.getTestProjectId());
				taTaskRequestBo.setTcIds(tntry.getValue().toArray(new Long[tntry.getValue().size()]));

				//获取当前项目最大taskId
				taTaskRequestBo.setTaTaskId(getCurrentTaTaskId(testProjectDto, taTaskRequestBo.getPlanStepId(), taTaskRequestBo.getTestPlanId()));
				//todo 插入log
				TestTaTaskLogDto testTaTaskLogDto = new TestTaTaskLogDto();

				testTaTaskLogDto.setTaTaskId(taTaskRequestBo.getTaTaskId());
				testTaTaskLogDto.setPlanStepId(taTaskRequestBo.getPlanStepId());
				testTaTaskLogDto.setTestPlanId(taTaskRequestBo.getTestPlanId());
				testTaTaskLogDto.setTestProjectId(taTaskRequestBo.getTestProjectId());
				testTaTaskLogDto.setIsActual(Boolean.TRUE);
				testTaTaskLogDto.setState(Boolean.TRUE);
				testTaTaskLogDto.setMemo("定时任务触发");
				testTaTaskLogDto.setAllCnt(taTaskRequestBo.getTcIds().length);

				taMng.insertTaTaskLog(testTaTaskLogDto);

				triggerTaTask(taTaskRequestBo);//触发任务

			}
		}

	}

	private String getCurrentTaTaskId(TestProjectDto testProjectDto, Long planStepId, Long planId) {
		TaTask taTask = taTaskMng.getLastTaskByStepId(planStepId);
		int num = 1;
		if (taTask != null) {
			String taTaskId = taTask.getTaTaskId();
			String[] taTaskItem = taTaskId.split("-");
			if (taTaskItem.length > 2) {
				num = Integer.valueOf(taTaskItem[2]) + 1;
			}
		}
		return testProjectDto.getProjectname() + "-" + planId + "-" + num;
	}

	private void requestJob(String jobName, Long idTaTask, TaTaskRequestBo taTaskRequestBo) {
		HttpFixtureHelper requery = new HttpFixtureHelper();
		StringBuilder jenKinsUrlBuilder = new StringBuilder();
		jenKinsUrlBuilder.append(jenKinsUrl);
		jenKinsUrlBuilder.append("job/");
		jenKinsUrlBuilder.append(jobName);//动态获取
		jenKinsUrlBuilder.append("/buildWithParameters?");
		jenKinsUrlBuilder.append(TaJobUtil.ID_TA_TASK);
		jenKinsUrlBuilder.append("=");
		jenKinsUrlBuilder.append(idTaTask);
		jenKinsUrlBuilder.append("&delay=");
		jenKinsUrlBuilder.append(jenKinsJobDelaySec);
		jenKinsUrlBuilder.append("sec");

		jenKinsUrlBuilder.append("&");
		jenKinsUrlBuilder.append(TaJobUtil.STAGE_ID);
		jenKinsUrlBuilder.append("=");
		jenKinsUrlBuilder.append(taTaskRequestBo.getStageId());

		jenKinsUrlBuilder.append("&");
		jenKinsUrlBuilder.append(TaJobUtil.GROUP_ID);
		jenKinsUrlBuilder.append("=");
		jenKinsUrlBuilder.append(StringUtils.hasLength(taTaskRequestBo.getGroupId()) ? taTaskRequestBo.getGroupId() : UnitUtil.GROUPID_T);

		requery.setUrl(jenKinsUrlBuilder.toString());
		requery.Post();
	}

	//	/*
	//	 * 日期偏移运算(增、减几日）
	//	 */
	//	public String getCycleId() {
	//		GregorianCalendar cal = new GregorianCalendar();
	//		cal.setTime(new Date());
	//		cal.add(GregorianCalendar.DAY_OF_MONTH, 1);
	//		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	//		return "#" + dateFormat.format(cal.getTime());
	//	}

	/*
	* 取本周7天的第一天（周一的日期）
	*/
	public static String getCycleId() {
		int mondayPlus;
		Calendar cd = Calendar.getInstance();
		// 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
		int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
		if (dayOfWeek <= 3) {//星期二或之前 上线日期是星期二
			mondayPlus = 3 - dayOfWeek;
		} else if (dayOfWeek <= 5) {//星期二之后星期四或之前 上线日期是星期四
			mondayPlus = 5 - dayOfWeek;
		} else {//星期四之后上线日期是下星期二
			mondayPlus = 7 - dayOfWeek + 3;
		}
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.add(GregorianCalendar.DATE, mondayPlus);
		Date monday = currentDate.getTime();

		return "#" + DateUtil.parseFromDate(monday);

	}

	public void setTaTaskMng(TaTaskMng taTaskMng) {
		this.taTaskMng = taTaskMng;
	}

	public void setJenKinsUrl(String jenKinsUrl) {
		this.jenKinsUrl = jenKinsUrl;
	}

	public void setTaMng(TaMng taMng) {
		this.taMng = taMng;
	}

	public void setTaProjectMng(TaProjectMng taProjectMng) {
		this.taProjectMng = taProjectMng;
	}

	public void setSvnUserName(String svnUserName) {
		this.svnUserName = svnUserName;
	}

	public void setSvnPassword(String svnPassword) {
		this.svnPassword = svnPassword;
	}

	public String getJenKinsJobDelaySec() {
		return jenKinsJobDelaySec;
	}

	public void setJenKinsJobDelaySec(String jenKinsJobDelaySec) {
		this.jenKinsJobDelaySec = jenKinsJobDelaySec;
	}

	public void setAssoTaTaskTestCaseMng(AssoTaTaskTestCaseMng assoTaTaskTestCaseMng) {
		this.assoTaTaskTestCaseMng = assoTaTaskTestCaseMng;
	}

	public void autoTiggerTask4Regression() {
		List<TestProjectDto> testProjectDtos = taMng.findTestProjects();//获取所有项目组
		for (TestProjectDto testProjectDto : testProjectDtos) {
			autoTiggerTask4RegressionProcess(testProjectDto);
		}
	}

	private void autoTiggerTask4RegressionProcess(TestProjectDto testProjectDto) {

		List<Long> regressionTcIds = taMng.getTcIdsByProjectRegression(testProjectDto.getTeemId());

		if (regressionTcIds != null) {

			TaTaskRequestBo taTaskRequestBo = new TaTaskRequestBo();
			taTaskRequestBo.setIsActual(true);
			taTaskRequestBo.setTestPlanId(Long.valueOf(testProjectDto.getTeemId() + getTestPlanId()));
			taTaskRequestBo.setPlanStepId(taTaskRequestBo.getTestPlanId());
			taTaskRequestBo.setTestProjectId(testProjectDto.getTestProjectId());
			taTaskRequestBo.setTcIds(regressionTcIds.toArray(new Long[regressionTcIds.size()]));

			taTaskRequestBo.setTaTaskId(taTaskRequestBo.getTestPlanId().toString());
			// 插入log
			TestTaTaskLogDto testTaTaskLogDto = new TestTaTaskLogDto();

			testTaTaskLogDto.setTaTaskId(taTaskRequestBo.getTaTaskId());
			testTaTaskLogDto.setPlanStepId(taTaskRequestBo.getPlanStepId());
			testTaTaskLogDto.setTestPlanId(taTaskRequestBo.getTestPlanId());
			testTaTaskLogDto.setTestProjectId(taTaskRequestBo.getTestProjectId());
			testTaTaskLogDto.setIsActual(Boolean.TRUE);
			testTaTaskLogDto.setState(Boolean.TRUE);
			testTaTaskLogDto.setMemo("回归测试定时任务触发");
			testTaTaskLogDto.setAllCnt(taTaskRequestBo.getTcIds().length);
			taMng.insertTaTaskLog(testTaTaskLogDto);
			triggerTaTask(taTaskRequestBo);//触发任务

		}

	}

	/*
	 * 日期偏移运算(增、减几日）
	 */
	public static String getTestPlanId() {
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(new Date());
		//		cal.add(GregorianCalendar.DAY_OF_MONTH, 1);
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhh");
		return dateFormat.format(cal.getTime());
	}

	public static void main(String[] args) {
		System.out.println(getTestPlanId());
	}

}
